package com.sdhs.analyze.schedule;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sdhs.analyze.bean.*;
import com.sdhs.analyze.bean.network.NetWork;
import com.sdhs.analyze.bean.org.OrgInfo;
import com.sdhs.analyze.common.ConstantEnum;
import com.sdhs.analyze.service.InfoNodeStatusService;
import com.sdhs.analyze.service.InfoNodeStatusTraceService;
import com.sdhs.analyze.service.InfoUserMessageService;
import com.sdhs.analyze.service.OrgService;
import com.sdhs.analyze.utils.DateUtils;
import com.sdhs.analyze.utils.NumberUtils;
import com.sdhs.analyze.utils.RedisUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.TimeUnit;


@Component
public class InfoGantryTask {
    private static Logger logger = LoggerFactory.getLogger(InfoGantryTask.class);
    @Autowired
    private InfoNodeStatusTraceService infoNodeStatusTraceService;
    @Autowired
    private InfoNodeStatusService infoNodeStatusService;
    @Autowired
    private InfoUserMessageService infoUserMessageService;
    @Autowired
    private OrgService orgService;
    @Autowired
    private RedisUtil redisUtil;

    private String split = "|";
    private String frontName = "前端工控机";
    private String backName = "后台服务器";
    private String vehicleName = "车检器";
    private String weatherName = "气象监测检设备";
    private String className = "车型检测设备";
    private String loadName = "载重检测设备";
    private String tempName = "温控设备";
    private String powerName = "供电设备";
    private String cameraName = "牌识设备";
    private String rsuName = "天线控制器";
    private String psamName = "PSAM";
    private String antennalName = "天线头";


//    @KafkaListener(topics = "TGHBU")
    public void statusTask(String json){
/*        String key = gantryBackId+":"+"1"+":"+"1"+"nodeMonitorInfo";
        String statusJson = redisUtil.get(key);
        InfoGantryStatus status = JSON.parseObject(statusJson, InfoGantryStatus.class);*/
        System.out.println("接收数据");
        InfoGantryStatus status  = JSON.parseObject(json,InfoGantryStatus.class);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        /* 接收超过十分钟，不予处理 */
        calendar.add(Calendar.MINUTE, -10);
        /* 过期监测信息不处理 */
        if(status.getTimeInsert().before(calendar.getTime()) == true) {
            logger.info("监测信息接收超过5分钟，不处理");
            return;
        }
        Map<String,InfoNodeStatus> map = infoNodeStatusService.selectByNodeType();
        try {
            handleStatus(status, map);
        }
        catch (NullPointerException ex) {
            logger.debug("空指针异常，暂时忽略，待处理", ex);
            logger.error(json);
            logger.error(ex.getMessage());
        }catch (Exception e){
            logger.error("数据分析异常！");
            logger.error(e.getMessage());
            logger.error(json);
        }
    }


    public void handleStatus(InfoGantryStatus status,Map<String,InfoNodeStatus> nodeStatusMap){
        String chargeUnitId = status.getChargeUnitId();
        InfoNodeStatus infoNodeStatus = nodeStatusMap.get("1");
        Map<String, OrgInfo> orgInfo = orgService.getGantrySystemOrgInfoMap(chargeUnitId);
        frontSystem(status,nodeStatusMap,orgInfo);
        // 后端
        List<InfoGantryStatusBack> chargeUnitHeartbeatList = status.getChargeUnitHeartbeatList();
        if(chargeUnitHeartbeatList != null && chargeUnitHeartbeatList.size() > 0){
            operaBackStatus(chargeUnitHeartbeatList,nodeStatusMap,orgInfo);
        }
        String orgName = orgInfo.get(chargeUnitId).getOrgName();
        String parentNodeType = infoNodeStatus.getParentNodeType();
        Integer maxNum = infoNodeStatusService.selectMaxNum(chargeUnitId,"1");
        saveNode(chargeUnitId,"1",orgName,null,parentNodeType,chargeUnitId,infoNodeStatus.getOrgType(),infoNodeStatus.getDisplayLevel(),maxNum,new Date());
    }

    public void frontSystem(InfoGantryStatus status,Map<String,InfoNodeStatus> nodeStatusMap,Map<String, OrgInfo> orgInfo){
        // 前端系统
        List<InfoGantryStatusFront> gantryHeartbeatList = status.getGantryHeartbeatList();
        Map<String,Integer> map = new HashMap();
        if(gantryHeartbeatList != null && gantryHeartbeatList.size() > 0){
            map = operaFrontStatus(gantryHeartbeatList,map,nodeStatusMap,orgInfo);
        }
        // 车检器
        List<InfoGantryStatusVehicle> vehicleDetectorHeartbeatList = status.getVehicleDetectorHeartbeatList();
        if(vehicleDetectorHeartbeatList != null && vehicleDetectorHeartbeatList.size() > 0){
            map = operaVehicleStatus(vehicleDetectorHeartbeatList,map,nodeStatusMap,orgInfo);
        }
        // 其他
        List<InfoGantryStatusOther> otherHeartbeatList = status.getOtherHeartbeatList();
        if(otherHeartbeatList != null && otherHeartbeatList.size() > 0){
            map = operaOtherStatus(otherHeartbeatList,map,nodeStatusMap,orgInfo);
        }
        // 车牌图像识别设备心跳（数组）
        List<InfoGantryStatusCamera> cameraHeartbeatList = status.getCameraHeartbeatList();
        if(cameraHeartbeatList != null && cameraHeartbeatList.size() > 0){
            map = opreaCameraStatus(cameraHeartbeatList,map,nodeStatusMap,orgInfo);
        }
        // RSU
        List<InfoGantryStatusRSU> rsuHeartbeatList = status.getRSUHeartbeatList();
        if(rsuHeartbeatList != null && rsuHeartbeatList.size()>0){
            map = opreaRSUStatus(rsuHeartbeatList,map,nodeStatusMap,orgInfo);
        }
        Iterator keys = map.keySet().iterator();
        while(keys.hasNext()){
            String gantryId = (String)keys.next();
            // 前端系统
            InfoNodeStatus infoNodeStatus = nodeStatusMap.get("2");
            int maxNum = infoNodeStatusService.selectMaxNum(gantryId, "2");
            String orgName = orgInfo.get(gantryId).getOrgName();
            InfoNodeStatusTrace infoNodeStatusTrace = infoNodeStatusTraceService.selectOne(gantryId, "2");
            String desc = "前端系统异常";
            String nodeName = orgName + split + "前端系统";
            operaStatus(infoNodeStatusTrace,maxNum,gantryId,infoNodeStatus.getOrgType(),gantryId,"2",desc,nodeName,new Date());
            saveNode(gantryId,"2",orgName,status.getChargeUnitId(),infoNodeStatus.getParentNodeType(),gantryId,infoNodeStatus.getOrgType(),infoNodeStatus.getDisplayLevel(),maxNum,new Date());
        }
    }

    private Map operaFrontStatus(List<InfoGantryStatusFront> gantryHeartbeatList,Map<String,Integer> map,Map<String,InfoNodeStatus> nodeStatusMap,Map<String, OrgInfo> orgInfo){

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, -15);
        for (InfoGantryStatusFront igsf : gantryHeartbeatList){
            Integer frontComputerOrder = igsf.getFrontComputerOrder();
            String name = frontComputerOrder == 1?"主机":"备机";
            String gantryId = igsf.getGantryId();
            String nodeId = gantryId + split + frontComputerOrder;
            String nodeName = orgInfo.get(gantryId).getOrgName() + split + frontName+ split + name;
            Date frontStateTime = igsf.getFrontStateTime();
            /* 数据生成时间超过15分钟，不予处理 */
            if(frontStateTime.before(calendar.getTime())) {
                continue;
            }
            InfoNodeStatus ins =  nodeStatusMap.get("3");
            // 前端软件
            String frontSoftState = igsf.getFrontSoftState();
            String descSoftState = frontName + name + ConstantEnum.FRONT_SOFT_STATUS.getNodeDesc();
            operaSoftStatus(nodeId,frontSoftState,gantryId,frontStateTime,3,ConstantEnum.FRONT_SOFT_STATUS.getNodeType(),nodeName,descSoftState,nodeStatusMap);
            // 硬件资源平均负载状态
            String frontLoadAverage = igsf.getFrontLoadAverage();
            String descLoadAverage = frontName + name + ConstantEnum.FRONT_LOAD_AVG.getNodeDesc();
            handleOneValueStatus(nodeId,frontLoadAverage,1,2,gantryId,frontStateTime,3,ConstantEnum.FRONT_LOAD_AVG.getNodeType(),nodeName,descLoadAverage,nodeStatusMap);
            // 积压通行流水状态
            Integer frontOverTradeCount = igsf.getFrontOverTradeCount();
            String descOverTradeCount = frontName + name + ConstantEnum.FRONT_OVER_TRADE.getNodeDesc();
            operaCountStatus(nodeId,frontOverTradeCount,3,gantryId,frontStateTime,3,ConstantEnum.FRONT_OVER_TRADE.getNodeType(),nodeName,descOverTradeCount,nodeStatusMap);
            // 传输异常通行流水状态
            Integer frontTransErrTradeCount = igsf.getFrontTransErrTradeCount();
            String descTransErrTradeCount = frontName + name + ConstantEnum.FRONT_TRANS_ERR_TRADE.getNodeDesc();
            operaCountStatus(nodeId,frontTransErrTradeCount,4,gantryId,frontStateTime,3,ConstantEnum.FRONT_TRANS_ERR_TRADE.getNodeType(),nodeName,descTransErrTradeCount,nodeStatusMap);
            // 积压牌识流水状态
            Integer frontOverVehDataCount = igsf.getFrontOverVehDataCount();
            String descOverVehDataCount = frontName + name + ConstantEnum.FRONT_OVER_VEH_DATE.getNodeDesc();
            operaCountStatus(nodeId,frontOverVehDataCount,5,gantryId,frontStateTime,3,ConstantEnum.FRONT_OVER_VEH_DATE.getNodeType(),nodeName,descOverVehDataCount,nodeStatusMap);
            // 传输异常牌识流水状态
            Integer frontTransErrVehDataCount = igsf.getFrontTransErrVehDataCount();
            String descTransErrVehDataCount = frontName + name + ConstantEnum.FRONT_TRANS_ERR_VEH_DATE.getNodeDesc();
            operaCountStatus(nodeId,frontTransErrVehDataCount,6,gantryId,frontStateTime,3,ConstantEnum.FRONT_TRANS_ERR_VEH_DATE.getNodeType(),nodeName,descTransErrVehDataCount,nodeStatusMap);
            // 数据盘使用状态
            String frontDiskDataLeftSize = igsf.getFrontDiskDataLeftSize();
            String frontDiskDataTotalSize = igsf.getFrontDiskDataTotalSize();
            String descDiskData = frontName + name + ConstantEnum.FRONT_DISK_DATE.getNodeDesc();
            handleTwoValueStatus(nodeId,frontDiskDataLeftSize,frontDiskDataTotalSize,7,8,gantryId,frontStateTime,3,ConstantEnum.FRONT_DISK_DATE.getNodeType(),nodeName,descDiskData,nodeStatusMap);
            // 运行盘使用状态
            String frontDiskRunLeftSize = igsf.getFrontDiskRunLeftSize();
            String frontDiskRunTotalSize = igsf.getFrontDiskRunTotalSize();
            String descDiskRunData = frontName + name + ConstantEnum.FRONT_DISK_RUN.getNodeDesc();
            handleTwoValueStatus(nodeId,frontDiskRunLeftSize,frontDiskRunTotalSize,9,10,gantryId,frontStateTime,3,ConstantEnum.FRONT_DISK_RUN.getNodeType(),nodeName,descDiskRunData,nodeStatusMap);
            // CPU使用状态
            String frontCpuRate = igsf.getFrontCpuRate();
            String descCpuRate = frontName + name + ConstantEnum.FRONT_CPU_RATE.getNodeDesc();
            handleOneValueStatus(nodeId,frontCpuRate,11,12,gantryId,frontStateTime,3,ConstantEnum.FRONT_CPU_RATE.getNodeType(),nodeName,descCpuRate,nodeStatusMap);
            // 物理内存使用状态
            String memory = igsf.getFrontMemoryRate();
            String descMemory = frontName + name + ConstantEnum.FRONT_MEMORY_RATE.getNodeDesc();
            handleOneValueStatus(nodeId,memory,13,14,gantryId,frontStateTime,3,ConstantEnum.FRONT_MEMORY_RATE.getNodeType(),nodeName,descMemory,nodeStatusMap);
            // 前端北斗授时服务
            String frontBeidouState = igsf.getFrontBeidouState();
            String descBeidouState = frontName + name + ConstantEnum.FRONT_BEIDOU_STATUS.getNodeDesc();
            operaBeiDouStatus(nodeId,frontBeidouState,gantryId,frontStateTime,3,ConstantEnum.FRONT_BEIDOU_STATUS.getNodeType(),nodeName,descBeidouState,nodeStatusMap);
            // 前端工控机网络状态
            /*String descNetworkState = frontName + name + ConstantEnum.FRONT_NETWORK_STATUS.getNodeDesc();
            operaNetworkStatus(chargeUnitId,nodeId,gantryId,frontStateTime,3,ConstantEnum.FRONT_NETWORK_STATUS.getNodeType(),nodeName,descNetworkState,nodeStatusMap);*/
            // 前端工控机
            int maxNum = infoNodeStatusService.selectMaxNum(nodeId, "3");
            saveNode(nodeId,"3",nodeName,gantryId,ins.getParentNodeType(),gantryId,ins.getOrgType(),ins.getDisplayLevel(),maxNum,new Date());
            map.put(gantryId,1);
        }
        return map;
    }
    private void operaBackStatus(List<InfoGantryStatusBack> chargeUnitHeartbeatList,Map<String,InfoNodeStatus> nodeStatusMap,Map<String, OrgInfo> orgInfo){

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, -15);
        for(InfoGantryStatusBack igsb : chargeUnitHeartbeatList){
            Integer backComputerOrder = igsb.getBackComputerOrder();
            String name = backComputerOrder == 1?"主机":"备机";
            String chargeUnitId = igsb.getChargeUnitId();
            String nodeName = orgInfo.get(chargeUnitId).getOrgName() + split + backName+ split + name;
            Date backStateTime = igsb.getBackStateTime();
            /* 信息产生超过15分钟，不处理 */
            if(backStateTime.before(calendar.getTime())) {
                continue;
            }
            String nodeId = chargeUnitId + split + backComputerOrder;
            InfoNodeStatus ins =  nodeStatusMap.get("4");
            // 后台软件
            String backSoftState = igsb.getBackSoftState();
            String descSoftState = backName + name + ConstantEnum.BACK_SOFT_STATUS.getNodeDesc();
            operaSoftStatus(nodeId,backSoftState,chargeUnitId,backStateTime,2,ConstantEnum.BACK_SOFT_STATUS.getNodeType(),nodeName,descSoftState,nodeStatusMap);
            // 硬件资源平均负载状态
            String backLoadAverage = igsb.getBackLoadAverage();
            String descLoadAverage = backName + name + ConstantEnum.BACK_LOAD_AVG.getNodeDesc();
            handleOneValueStatus(nodeId,backLoadAverage,18,19,chargeUnitId,backStateTime,2,ConstantEnum.BACK_LOAD_AVG.getNodeType(),nodeName,descLoadAverage,nodeStatusMap);
            // 积压通行流水状态
            Integer backOverTradeCount = igsb.getBackOverTradeCount();
            String descOverTradeCount = backName + name + ConstantEnum.BACK_OVER_TRADE.getNodeDesc();
            operaCountStatus(nodeId,backOverTradeCount,20,chargeUnitId,backStateTime,2,ConstantEnum.BACK_OVER_TRADE.getNodeType(),nodeName,descOverTradeCount,nodeStatusMap);
            // 传输异常通行流水状态
            Integer backTransErrTradeCount = igsb.getBackTransErrTradeCount();
            String descTransErrTradeCount = backName + name + ConstantEnum.BACK_TRANS_ERR_TRADE.getNodeDesc();
            operaCountStatus(nodeId,backTransErrTradeCount,21,chargeUnitId,backStateTime,2,ConstantEnum.BACK_TRANS_ERR_TRADE.getNodeType(),nodeName,descTransErrTradeCount,nodeStatusMap);
            // 积压牌识流水状态
            Integer backOverVehDataCount = igsb.getBackOverVehDataCount();
            String descOverVehDataCount = backName + name + ConstantEnum.BACK_OVER_VEH_DATE.getNodeDesc();
            operaCountStatus(nodeId,backOverVehDataCount,22,chargeUnitId,backStateTime,2,ConstantEnum.BACK_OVER_VEH_DATE.getNodeType(),nodeName,descOverVehDataCount,nodeStatusMap);
            // 传输异常牌识流水状态
            Integer backTransErrVehDataCount = igsb.getBackTransErrVehDataCount();
            String descTransErrVehDataCount = backName + name + ConstantEnum.BACK_TRANS_ERR_VEH_DATE.getNodeDesc();
            operaCountStatus(nodeId,backTransErrVehDataCount,23,chargeUnitId,backStateTime,2,ConstantEnum.BACK_TRANS_ERR_VEH_DATE.getNodeType(),nodeName,descTransErrVehDataCount,nodeStatusMap);
            // modify by duanxin 20200107 因不传输图片，暂时关闭图片积压监控
            // 积压牌识图片状态
//            Integer backOverVehPicCount = igsb.getBackOverVehPicCount();
//            String descOverVehPicCount = backName + name + ConstantEnum.BACK_OVER_VEH_PIC.getNodeDesc();
//            operaCountStatus(nodeId,backOverVehPicCount,24,chargeUnitId,backStateTime,2,ConstantEnum.BACK_OVER_VEH_PIC.getNodeType(),nodeName,descOverVehPicCount,nodeStatusMap);
            // 传输异常牌识图片状态
//            Integer backTransErrVehPicCount = igsb.getBackTransErrVehPicCount();
//            String descTransErrVehPicCount = backName + name + ConstantEnum.BACK_TRANS_ERR_VEH_PIC.getNodeDesc();
//            operaCountStatus(nodeId,backTransErrVehPicCount,25,chargeUnitId,backStateTime,2,ConstantEnum.BACK_TRANS_ERR_VEH_PIC.getNodeType(),nodeName,descTransErrVehPicCount,nodeStatusMap);
            // 数据盘使用状态
            String backDiskDataLeftSize = igsb.getBackDiskDataLeftSize();
            String backDiskDataTotalSize = igsb.getBackDiskDataTotalSize();
            String descDiskData = backName + name + ConstantEnum.BACK_DISK_DATE.getNodeDesc();
            handleTwoValueStatus(nodeId,backDiskDataLeftSize,backDiskDataTotalSize,26,27,chargeUnitId,backStateTime,2,ConstantEnum.BACK_DISK_DATE.getNodeType(),nodeName,descDiskData,nodeStatusMap);
            // 运行盘使用状态
            String backDiskRunLeftSize = igsb.getBackDiskRunLeftSize();
            String backDiskRunTotalSize = igsb.getBackDiskRunTotalSize();
            String descDiskRunData = backName + name + ConstantEnum.BACK_DISK_RUN.getNodeDesc();
            handleTwoValueStatus(nodeId,backDiskRunLeftSize,backDiskRunTotalSize,28,29,chargeUnitId,backStateTime,2,ConstantEnum.BACK_DISK_RUN.getNodeType(),nodeName,descDiskRunData,nodeStatusMap);
            // CPU使用状态
            String backCPURate = igsb.getBackCPURate();
            String descCPURate = backName + name + ConstantEnum.BACK_CPU_RATE.getNodeDesc();
            handleOneValueStatus(nodeId,backCPURate,30,31,chargeUnitId,backStateTime,2,ConstantEnum.BACK_CPU_RATE.getNodeType(),nodeName,descCPURate,nodeStatusMap);
            // 物理内存使用状态
            String memory = igsb.getBackMemoryRate();
            String descMemory = backName + name + ConstantEnum.BACK_MEMORY_RATE.getNodeDesc();
            handleOneValueStatus(nodeId,memory,32,33,chargeUnitId,backStateTime,2,ConstantEnum.BACK_MEMORY_RATE.getNodeType(),nodeName,descMemory,nodeStatusMap);
            // 后台北斗授时服务
            String beidouState = igsb.getBackBeidouState();
            String descBeiDouStatus = backName + name + ConstantEnum.BACK_MEMORY_RATE.getNodeDesc();
            operaBeiDouStatus(nodeId,beidouState,chargeUnitId,backStateTime,2,ConstantEnum.BACK_BEIDOU_STATUS.getNodeType(),nodeName,descBeiDouStatus,nodeStatusMap);
            // 后台服务器网络状态
            /*String descNetworkState = backName + name + ConstantEnum.BACK_NETWORK_STATUS.getNodeDesc();
            operaNetworkStatus(chargeUnitId,nodeId,chargeUnitId,backStateTime,2,ConstantEnum.BACK_NETWORK_STATUS.getNodeType(),nodeName,descNetworkState,nodeStatusMap);*/
            int maxNum = infoNodeStatusService.selectMaxNum(nodeId, "4");
            saveNode(nodeId,"4",nodeName,chargeUnitId,ins.getParentNodeType(),chargeUnitId,ins.getOrgType(),ins.getDisplayLevel(),maxNum,backStateTime);
            InfoNodeStatusTrace infoNodeStatusTrace = infoNodeStatusTraceService.selectOne(nodeId, "4");
            String desc = backName+"异常";
            operaStatus(infoNodeStatusTrace,maxNum,chargeUnitId,ins.getOrgType(),nodeId,"4",desc,nodeName,backStateTime);
        }
    }
    // 前端软件 后端软件
    private void operaSoftStatus(String nodeId,String softState,String gantryId,Date stateTime,Integer orgType,String nodeType,String nodeName,String desc,Map<String,InfoNodeStatus> nodeStatusMap){
        // 前端软件运行状态  0-正常 1-异常 不同进程服务的状态，用分隔符“|”分隔
        int status = 0;
        String description = null;
        if(!softState.contains("1")){
            status = 0;
        }else {
            status = 2;
            description = desc;
        }
        handleDate(nodeStatusMap,nodeType,nodeId,status,gantryId,gantryId,orgType,description,nodeName,stateTime);
    }
    // 北斗授时服务状态 0-无响应 1-正常响应 2-无设备
    private void operaBeiDouStatus(String nodeId,String beidouState,String gantryId,Date stateTime,Integer orgType,String nodeType,String nodeName,String desc,Map<String,InfoNodeStatus> nodeStatusMap){
        int status = 0;
        String description = null;
        if(beidouState.equals("0")){
            status = 1;
            description = desc;
        }else if(beidouState.equals("1")){
            status = 0;
        }else if(beidouState.equals("2")){
            status = -2;
        }
        handleDate(nodeStatusMap,nodeType,nodeId,status,gantryId,gantryId,orgType,description,nodeName,stateTime);
    }

    // 网络状态 0未知，1成功，2失败
    private void operaNetworkStatus(String gantryBackId,String nodeId,String gantryId,Date stateTime,Integer orgType,String nodeType,String nodeName,String desc,Map<String,InfoNodeStatus> nodeStatusMap){
        String key = gantryBackId + split + 1+ split +1 +"nodeMonitorInfo"+ nodeId + nodeType;
        String json = redisUtil.get(key);
        NetWork netWork = JSON.parseObject(json, NetWork.class);
        Integer status = 0;
        String description = null;
        if (netWork != null){
            status = netWork.getStatus();
            if(status != null && status == 2){
                description = desc;
            }
            handleDate(nodeStatusMap,nodeType,nodeId,status,gantryId,gantryId,orgType,description,nodeName,stateTime);
        }
    }

    // 积压通行流水状态 传输异常牌识流水状态 积压牌识图片状态 传输异常牌识图片状态
    private void operaCountStatus(String nodeId,Integer count,Integer id,String chargeUnitId,Date stateTime,Integer orgType,String nodeType,String nodeName,String desc,Map<String,InfoNodeStatus> nodeStatusMap){
        // 阈值id 20
        String description = null;
        Threshold threshold = infoNodeStatusTraceService.selectThreshold(id);
        Float s1 = Float.parseFloat(threshold.getValue());
        int status;
        if(count == -1){
            status = -2;
        }else{
            if(count < s1){
                status = 0;
            }else{
                status = 1;
                description = desc+"高于"+s1;
            }
        }
        handleDate(nodeStatusMap,nodeType,nodeId,status,chargeUnitId,chargeUnitId,orgType,description,nodeName,stateTime);
    }
    // 数据盘使用状态  运行盘使用状态 使用量
    private void handleTwoValueStatus(String nodeId,String size1,String size2,int id1,int id2,String chargeUnitId,Date stateTime,Integer orgType,String nodeType,String nodeName,String desc,Map<String,InfoNodeStatus> nodeStatusMap){
        Threshold threshold = infoNodeStatusTraceService.selectThreshold(id1);
        Threshold threshold2 = infoNodeStatusTraceService.selectThreshold(id2);
        Float s1 = Float.parseFloat(threshold.getValue());
        Float s2 = Float.parseFloat(threshold2.getValue());
        float left;
        float total;
        if(size1.contains("GiB")){
            left = Float.parseFloat(NumberUtils.parseNum(size1));
            left = left*1024F;
        }else if(size1.contains("TiB")){
            left = Float.parseFloat(NumberUtils.parseNum(size1));
            left = left*1024F*1024F;
        }else{
            left = Float.parseFloat(size1);
        }
        if(size2.contains("GiB")){
            total = Float.parseFloat(NumberUtils.parseNum(size2));
            total = total*1024F;
        }else if(size2.contains("TiB")){
            total = Float.parseFloat(NumberUtils.parseNum(size2));
            total = total*1024F*1024F;
        }else{
            total = Float.parseFloat(size2);
        }
        Float value = (total - left)/total * 100;
        int status = 0;
        String description = null;
        if(StringUtils.isBlank(size1) || StringUtils.isBlank(size2)){
            status = -2;
        }else{
            if(value < s1){
                status = 0;
            }else if(s1 <= value && value < s2){
                status = 1;
                description = desc+"高于"+s1+"%";
            }else{
                status = 2;
                description = desc+"高于"+s2+"%";
            }
        }
        handleDate(nodeStatusMap,nodeType,nodeId,status,chargeUnitId,chargeUnitId,orgType,description,nodeName,stateTime);
    }
    // CPU使用状态  物理内存使用状态 硬件资源平均负载状态
    private void handleOneValueStatus(String nodeId,String rate,int id1,int id2,String chargeUnitId,Date stateTime,Integer orgType,String nodeType,String nodeName,String desc,Map<String,InfoNodeStatus> nodeStatusMap){
        Threshold threshold = infoNodeStatusTraceService.selectThreshold(id1);
        Threshold threshold2 = infoNodeStatusTraceService.selectThreshold(id2);
        Float s1 = Float.parseFloat(threshold.getValue());
        Float s2 = Float.parseFloat(threshold2.getValue());
        float value = Float.parseFloat(rate);
        int status = 0;
        String description = null;
        if(StringUtils.isBlank(rate)){
            status = -2;
        }else{
            if(value < s1){
                status = 0;
            }else if(s1 <= value && value < s2){
                status = 1;
                description = desc+"高于"+s1+"%";
            }else{
                status = 2;
                description = desc+"高于"+s2+"%";
            }
        }
        handleDate(nodeStatusMap,nodeType,nodeId,status,chargeUnitId,chargeUnitId,orgType,description,nodeName,stateTime);
    }
    // 车检器状态
    private Map operaVehicleStatus(List<InfoGantryStatusVehicle> vehicleDetectorHeartbeatList,Map<String,Integer> map,Map<String,InfoNodeStatus> nodeStatusMap,Map<String, OrgInfo> orgInfo){
        for(InfoGantryStatusVehicle igsv : vehicleDetectorHeartbeatList){
            String gantryId = igsv.getGantryId();
            String deviceId = igsv.getDeviceId();
            String nodeName = orgInfo.get(gantryId).getOrgName()+split + vehicleName + split + deviceId;
            // 车检器状态状态 0-无响应 1-正常响应 2-无设备
            String vehicleDetectorStatus = igsv.getVehicleDetectorStatus();
            Date vehicleDetectorStateTime = igsv.getVehicleDetectorStateTime();
            int status = 0;
            String description = null;
            if(vehicleDetectorStatus.equals("0")){
                status = 2;
                description = ConstantEnum.VEHICLE_DETECTOR_STATUS.getNodeDesc();
            }else if(vehicleDetectorStatus.equals("1")){
                status = 0;
            }else if(vehicleDetectorStatus.equals("2")){
                status = -2;
            }
            String nodeId = gantryId+deviceId;
            InfoNodeStatus infoNodeStatus = nodeStatusMap.get(ConstantEnum.VEHICLE_DETECTOR_STATUS.getNodeType());
            String parentNodeType = infoNodeStatus.getParentNodeType();
            Integer displayLevel = infoNodeStatus.getDisplayLevel();
            InfoNodeStatusTrace infoNodeStatusTrace = infoNodeStatusTraceService.selectOne(nodeId, ConstantEnum.VEHICLE_DETECTOR_STATUS.getNodeType());
            operaStatus(infoNodeStatusTrace,status,gantryId,3,nodeId, ConstantEnum.VEHICLE_DETECTOR_STATUS.getNodeType(),description,nodeName,vehicleDetectorStateTime);
            saveNode(nodeId,"5",nodeName,gantryId,parentNodeType,gantryId,3,displayLevel,status,vehicleDetectorStateTime);
            map.put(gantryId,1);
        }
        return map;
    }
    //其他设备
    private Map operaOtherStatus(List<InfoGantryStatusOther> otherHeartbeatList,Map<String,Integer> map,Map<String,InfoNodeStatus> nodeStatusMap,Map<String, OrgInfo> orgInfo){
        for (InfoGantryStatusOther isso : otherHeartbeatList){
            String gantryId = isso.getGantryId();
            String orgName = orgInfo.get(gantryId).getOrgName();
            String nodeName = orgName + split + "其它设备";
            // 气象检测设备状态
            String weatherDetectorStatus = isso.getWeatherDetectorStatus();
            String nodeName1 = nodeName + split + weatherName ;
            OtherStatus(weatherDetectorStatus,gantryId,3,ConstantEnum.OTHER_WEATHER_DETECTOR.getNodeType(),nodeName1,ConstantEnum.OTHER_WEATHER_DETECTOR.getNodeDesc(),nodeStatusMap);
            // 车型检测器状态 0-无响应 1-正常响应 2-无设备 涉及多个车型检测器设备状态以“|”分隔，按照由中置车道向应急车道方向按序填写。
            String classDetectorStatus = isso.getClassDetectorStatus();
            String nodeName2 = nodeName + split + className;
            OtherStatus(classDetectorStatus,gantryId,3,ConstantEnum.OTHER_CLASS_DETECTOR.getNodeType(),nodeName2,ConstantEnum.OTHER_CLASS_DETECTOR.getNodeDesc(),nodeStatusMap);
            // 载重检测器状态 0-无响应 1-正常响应 2-无设备 涉及多个载重检测器设备状态以“|”分隔，按照由中置车道向应急车道方向按序填写。
            String loadDetectorStatus = isso.getLoadDetectorStatus();
            String nodeName3 = nodeName + split + loadName;
            OtherStatus(loadDetectorStatus,gantryId,3,ConstantEnum.OTHER_LOAD_DETECTOR.getNodeType(),nodeName3,ConstantEnum.OTHER_LOAD_DETECTOR.getNodeDesc(),nodeStatusMap);
            // 温控设备状态 0-无响应 1-正常响应 2-无设备 涉及多个温控设备状态以“|”分隔
            String tempControllerStatus = isso.getTempControllerStatus();
            String nodeName4 = nodeName + split + tempName;
            OtherStatus(tempControllerStatus,gantryId,3,ConstantEnum.OTHER_TEMP_CONTROLLER.getNodeType(),nodeName4,ConstantEnum.OTHER_TEMP_CONTROLLER.getNodeDesc(),nodeStatusMap);
            // 供电设备状态 0-无响应 1-正常响应 2-无设备 涉及多个供电设备状态以“|”分隔
            String powerControllerStatus = isso.getPowerControllerStatus();
            String nodeName5 = nodeName + split + powerName;
            OtherStatus(powerControllerStatus,gantryId,3,ConstantEnum.OTHER_POWER_CONTROLLER.getNodeType(),nodeName5,ConstantEnum.OTHER_POWER_CONTROLLER.getNodeDesc(),nodeStatusMap);
            InfoNodeStatus ins = nodeStatusMap.get("6");
            int maxNum = infoNodeStatusService.selectMaxNum(gantryId, "6");
            saveNode(gantryId,"6",nodeName,gantryId,ins.getParentNodeType(),gantryId,ins.getOrgType(),ins.getDisplayLevel(),maxNum,new Date());
            map.put(gantryId,1);
        }
        return map;
    }
    private void OtherStatus(String otherStatus,String gantryId,Integer orgType,String nodeType,String nodeName,String desc,Map<String,InfoNodeStatus> nodeStatusMap){
        // 0-无响应 1-正常响应 2-无设备 涉及多个载重检测器设备状态以“|”分隔，按照由中置车道向应急车道方向按序填写。
        int status = 0;
        String description = null;
        if(StringUtils.isBlank(otherStatus)){
            status = -2;
        }else{
            if(!otherStatus.contains("0") && !otherStatus.contains("2")){
                status = 0;
            }else if(otherStatus.contains("0")){
                status = 1;
                description = desc;
            }else if(!otherStatus.contains("0") && otherStatus.contains("2")){
                status = -2;
            }
        }
        handleDate(nodeStatusMap,nodeType,gantryId,status,gantryId,gantryId,orgType,description,nodeName,new Date());
    }
    // 牌识设备
    private Map opreaCameraStatus(List<InfoGantryStatusCamera> cameraHeartbeatList,Map<String,Integer> map,Map<String,InfoNodeStatus> nodeStatusMap,Map<String, OrgInfo> orgInfo){

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, -15);
        for(InfoGantryStatusCamera camera : cameraHeartbeatList){
            String gantryId = camera.getGantryId();
            String chargeUnitId = camera.getChargeUnitId();
            Integer cameraNum = camera.getCameraNum();
            Date createTime = camera.getCreateTime();
            /* 数据生成时间超过15分钟，不处理 */
            if(createTime.before(calendar.getTime())) {
                continue;
            }
            String nodeId = gantryId +split+cameraNum;
            String orgName = orgInfo.get(gantryId).getOrgName();
            String nodeName = orgName + split + cameraName + split + cameraNum;
            InfoNodeStatus ins = nodeStatusMap.get("7");
            // 连接状态 0-断开，1-连接
            String connectStatus = camera.getConnectStatus();
            //cameraStatus(connectStatus,gantryId,3,ConstantEnum.CAMERA_CONNECT_STATUS.getNodeType(),nodeId,createTime,nodeName,ConstantEnum.CAMERA_CONNECT_STATUS.getNodeDesc(),nodeStatusMap);
            cameraStatus(connectStatus,gantryId,3,ConstantEnum.CAMERA_CONNECT_STATUS.getNodeType(),nodeId,createTime,nodeName,ConstantEnum.CAMERA_CONNECT_STATUS.getNodeDesc(),nodeStatusMap, 1);
            // 工作状态 0-关闭，1-工作
            String workStatus = camera.getWorkStatus();
            //cameraStatus(workStatus,gantryId,3,ConstantEnum.CAMERA_WORK_STATUS.getNodeType(),nodeId,createTime,nodeName,ConstantEnum.CAMERA_WORK_STATUS.getNodeDesc(),nodeStatusMap);
            cameraStatus(workStatus,gantryId,3,ConstantEnum.CAMERA_WORK_STATUS.getNodeType(),nodeId,createTime,nodeName,ConstantEnum.CAMERA_WORK_STATUS.getNodeDesc(),nodeStatusMap, 1);
            // 补光灯的工作状态 0-关闭，1-工作
            //String lightWorkStatus = camera.getLightWorkStatus();
            //cameraStatus(lightWorkStatus,gantryId,3,ConstantEnum.CAMERA_LIGHT_WORK_STATUS.getNodeType(),nodeId,createTime,nodeName,ConstantEnum.CAMERA_LIGHT_WORK_STATUS.getNodeDesc(),nodeStatusMap);
            //临时关闭补光灯报警
            //cameraStatus(lightWorkStatus,gantryId,3,ConstantEnum.CAMERA_LIGHT_WORK_STATUS.getNodeType(),nodeId,createTime,nodeName,ConstantEnum.CAMERA_LIGHT_WORK_STATUS.getNodeDesc(),nodeStatusMap, 1);
            // 牌识设备识别成功率
            String recognitionRate = camera.getRecognitionRate();
            cameraRate(recognitionRate,gantryId,3,ConstantEnum.CAMERA_REC_RATE.getNodeType(),nodeId,createTime,nodeName,ConstantEnum.CAMERA_REC_RATE.getNodeDesc(),nodeStatusMap);
            // 牌识设备网络状态
           /* String descNetworkState = nodeName + ConstantEnum.CAMERA_NETWORK_STATUS.getNodeDesc();
            operaNetworkStatus(chargeUnitId,nodeId,gantryId,createTime,3,ConstantEnum.CAMERA_NETWORK_STATUS.getNodeType(),nodeName,descNetworkState,nodeStatusMap);*/
            int maxNum = infoNodeStatusService.selectMaxNum(nodeId, "7");
            saveNode(nodeId,"7",nodeName,gantryId,ins.getParentNodeType(),gantryId,ins.getOrgType(),ins.getDisplayLevel(),maxNum,createTime);
            map.put(gantryId,1);
        }
        return map;
    }
    private void cameraStatus(String cameraStatus,String gantryId,Integer orgType,String nodeType,String nodeId,Date createTime,String nodeName,String description,Map<String,InfoNodeStatus> nodeStatusMap, int excStatus){
        int status = 0;
        String desc = null;
        if(cameraStatus.equals("0")){
            status = excStatus;
            desc = description;
        }else if(cameraStatus.equals("1")){
            status = 0;
        }
        handleDate(nodeStatusMap,nodeType,nodeId,status,gantryId,gantryId,orgType,desc,nodeName,createTime);
    }
    private void cameraRate(String recognitionRate,String gantryId,Integer orgType,String nodeType,String nodeId,Date createTime,String nodeName,String prefix,Map<String,InfoNodeStatus> nodeStatusMap){
        Threshold threshold = infoNodeStatusTraceService.selectThreshold(15);
        Float s1 = Float.parseFloat(threshold.getValue());
        float rate = Float.parseFloat(recognitionRate);
        int status = 0;
        String desc = null;
        if(StringUtils.isBlank(recognitionRate)){
            status = -2;
        }else{
            if(rate > s1){
                status = 0;
            }else{
                status = 1;
                Float f = rate -s1;
                desc = prefix +"低于" +s1+"%";
            }
        }
        handleDate(nodeStatusMap,nodeType,nodeId,status,gantryId,gantryId,orgType,desc,nodeName,createTime);
    }

    // Rsu设备
    private Map opreaRSUStatus(List<InfoGantryStatusRSU> rsuHeartbeatList,Map<String,Integer> map,Map<String,InfoNodeStatus> nodeStatusMap,Map<String, OrgInfo> orgInfo){

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, -15);
        /* modify by duanxin 20200108 对rsu状态进行综合判断，如主备均出现问题，则会告警，否则状态为提示 */
        /* 修改逻辑为：
            1、首先进行各项状态判定，并存入map
            2、判断发生异常后，如全部异常，则进行告警，否则，视为正常
         */
        Map<String, InfoNodeStatus> nodeStatusCheckMap = new HashMap<>();
        Map<String, Integer> controlStatusMap = new HashMap<>();
        Map<String, Integer> controlCntMap = new HashMap<>();
        int exceptionLevel = -3;
        /* 获取门架天线控制器数量 */
        for (int i=0; i<rsuHeartbeatList.size(); i++) {
            InfoGantryStatusRSU rsu = rsuHeartbeatList.get(i);
            String gantryId = rsu.getGantryId();
            Integer controlCnt = controlCntMap.get(gantryId);
            if(controlCnt == null) {
                controlCnt = 0;
            }
            Date createTime = rsu.getCreateTime();
            /* 数据生成时间超过15分钟，不处理 */
            if (createTime.before(calendar.getTime())) {
                continue;
            }
            controlCnt ++;
            controlCntMap.put(gantryId, controlCnt);
        }
        /* 循环判断节点状态 */
        for (int i=0; i<rsuHeartbeatList.size(); i++){
            int tmpControlStatus = 0;
            InfoGantryStatusRSU rsu = rsuHeartbeatList.get(i);
            String gantryId = rsu.getGantryId();
            Integer controlCnt = controlCntMap.get(gantryId);
            /* 缺失某个控制器状态，不进行处理 */
            if(controlCnt == null || controlCnt != 2) {
                logger.info(gantryId + "rsu控制器状态不完整或已过期，丢弃:" + JSONObject.toJSONString(rsuHeartbeatList));
                continue;
            }

            String controlOrder = rsu.getControlId();
            /* controlOrder 取值为1,2 */
            int controlOrderInt = Integer.valueOf(controlOrder);
            String orgName = orgInfo.get(gantryId).getOrgName();
            Date createTime = rsu.getCreateTime();
            String nodeId = gantryId +split + controlOrder;
            String nodeName = orgName + split + rsuName + controlOrder;
            InfoNodeStatus ins = nodeStatusMap.get("8");
            // 路侧单元主状态参数 11 21 表示正常，否则表示异常
            String rsuStatus = rsu.getRSUStatus();
            int mainStatus = rsuMainStatusCheck(rsuStatus,gantryId,3,ConstantEnum.RSU_STATUS.getNodeType(),
                    nodeId,nodeName,createTime,ConstantEnum.RSU_STATUS.getNodeDesc(),nodeStatusMap,
                    exceptionLevel,nodeStatusCheckMap);
            if(mainStatus == exceptionLevel) {
                tmpControlStatus = mainStatus;
            }

            // RSU控制板温度状态
            String rsuTemperature = rsu.getRSUTemperature();
            int rsuTemperatureStatus = rsuTemperatureCheck(rsuTemperature,gantryId,3,ConstantEnum.RSU_TEMP.getNodeType(),
                    nodeId,nodeName,createTime,ConstantEnum.RSU_TEMP.getNodeDesc(),nodeStatusMap,
                    exceptionLevel,nodeStatusCheckMap);
            if(rsuTemperatureStatus == exceptionLevel) {
                tmpControlStatus = rsuTemperatureStatus;
            }

            // RSU主备控制器间连接状态 1 通讯正常，2 通讯异常
            String controlNetWrok = rsu.getControlNetWrok();
            int controlNetWorkStatus = rsuControlNetWrokCheck(controlNetWrok,gantryId,3,ConstantEnum.RSU_CONTROLLER_NEWWORK.getNodeType(),
                    nodeId,nodeName,createTime,ConstantEnum.RSU_CONTROLLER_NEWWORK.getNodeDesc(),nodeStatusMap,
                    exceptionLevel,nodeStatusCheckMap);
            if(controlNetWorkStatus == exceptionLevel) {
                tmpControlStatus = controlNetWorkStatus;
            }

            // RSU设备网络状态
           /*String descNetworkState = nodeName + ConstantEnum.RSU_NETWORK_STATUS.getNodeDesc();
            operaNetworkStatus(chargeUnitId,nodeId,gantryId,createTime,3,ConstantEnum.RSU_NETWORK_STATUS.getNodeType(),nodeName,descNetworkState,nodeStatusMap);*/
            List<InfoGantryStatusRSUPSAM> psamInfoList = rsu.getPSAMInfoList();
            for (InfoGantryStatusRSUPSAM psam : psamInfoList){
                // PSAM状态 1 正常，2 异常，3 未授权，4 授权失败
                String status = psam.getStatus();
                String channelId = psam.getChannelId();
                String nodeId3 = nodeId + split + channelId;
                String nodeName3 = nodeName + split + psamName+ channelId;
                int rsuPsamStatus = rsuPsamStatusCheck(status, gantryId, 3, ConstantEnum.RSU_PSAM_ERROR.getNodeType(), rsuName, nodeName3,
                        controlOrder, nodeId3, createTime,nodeStatusMap,
                        exceptionLevel, nodeStatusCheckMap);
                if(rsuPsamStatus == exceptionLevel) {
                    tmpControlStatus = rsuPsamStatus;
                }
            }
            List<InfoGantryStatusRSUAntennal> antennalInfoList = rsu.getAntennalInfoList();
            if(antennalInfoList != null) {
                for (InfoGantryStatusRSUAntennal antennal : antennalInfoList) {
                    // RSU 天线头
                    // 通信状态(1 位)，1 正常，2 异常；
                    // 天线信道(1 位)，1 信道 1，2 信道2；功率等级(2 位)，取值 01～31；
                    // 发射状态(1 位)，1 正常，2 异常；接收状态(1 位)，1 正常，2 异常；
                    String status = antennal.getStatus();
                    String antennaId = antennal.getAntennaId();
                    String nodeId2 = gantryId + split + antennaId;
                    String nodeName2 = orgName + split + antennalName + antennaId;
                    InfoNodeStatus infoNodeStatus = nodeStatusMap.get("10");
                    // 天线头温度状态
                    String antennalTemperature = antennal.getAntennaTemperature();
                    if (StringUtils.isNotBlank(antennalTemperature)) {
                        rsuRSUAnteTempStatus(antennalTemperature, gantryId, 3, ConstantEnum.RSU_ANTENNA_TEMP.getNodeType(), nodeName2, antennaId, createTime, ConstantEnum.RSU_ANTENNA_TEMP.getNodeDesc(), nodeStatusMap);
                    }
                    if(StringUtils.isNotBlank(status)){
                        // 天线头通信状态 1 正常，2 异常；
                        String sub1 = status.substring(0, 1);
                        rsuRSUAnteStatus(sub1, gantryId, 3, ConstantEnum.RSU_ANTENNA_COMM_STATUS.getNodeType(), nodeName2, antennaId, createTime, ConstantEnum.RSU_ANTENNA_COMM_STATUS.getNodeDesc(), nodeStatusMap);
                        // 天线头发射状态 1 正常，2 异常；
                        String sub2 = status.substring(4, 5);
                        rsuRSUAnteStatus(sub2, gantryId, 3, ConstantEnum.RSU_ANTENNA_EMISSION_STATUS.getNodeType(), nodeName2, antennaId, createTime, ConstantEnum.RSU_ANTENNA_EMISSION_STATUS.getNodeDesc(), nodeStatusMap);
                        // 天线头接收状态 1 正常，2 异常；
                        String sub3 = status.substring(5, 6);
                        rsuRSUAnteStatus(sub3, gantryId, 3, ConstantEnum.RSU_ANTENNA_RECEIVE_STATUS.getNodeType(), nodeName2, antennaId, createTime, ConstantEnum.RSU_ANTENNA_RECEIVE_STATUS.getNodeDesc(), nodeStatusMap);
                    }
                    int maxNumAntennal = infoNodeStatusService.selectMaxNum(nodeId2, "10");
                    saveNode(nodeId2, "10", nodeName2, gantryId, ins.getParentNodeType(), gantryId, infoNodeStatus.getOrgType(), infoNodeStatus.getDisplayLevel(), maxNumAntennal, createTime);
                }
            }
            Integer controlStatus = controlStatusMap.get(gantryId);
            if(controlStatus == null) {
                controlStatus = 0x00;
            }
            /* 保存门架天线控制器异常状态 */
            if(tmpControlStatus == exceptionLevel) {
                controlStatus |= controlOrderInt;
            }
            controlStatusMap.put(gantryId, controlStatus);
            // 判断天线控制器的状态，如最大状态>0，则异常，否则，如最小状态为-3，则提示
            Integer maxNum = infoNodeStatusService.selectMaxNum(nodeId, "8");
            Integer minNum = infoNodeStatusService.selectMinNum(nodeId, "8");
            if(maxNum == null) {
                maxNum = 0;
            }
            if(minNum == null) {
                minNum = 0;
            }
            InfoNodeStatus nodeStatusCheck = new InfoNodeStatus();
            nodeStatusCheck.setNodeId(nodeId);
            nodeStatusCheck.setNodeType("8");
            nodeStatusCheck.setNodeName(nodeName);
            nodeStatusCheck.setParentNodeId(gantryId);
            nodeStatusCheck.setParentNodeType(ins.getParentNodeType());
            nodeStatusCheck.setOrgId(gantryId);
            nodeStatusCheck.setOrgType(ins.getOrgType());
            nodeStatusCheck.setDisplayLevel(ins.getDisplayLevel());
            if(maxNum > 0) {
                nodeStatusCheck.setStatus(maxNum);
            }
            else {
                nodeStatusCheck.setStatus(minNum);
            }
            nodeStatusCheck.setStatusCheckTime(createTime);
            nodeStatusCheckMap.put(nodeId, nodeStatusCheck);
//            saveNode(nodeId,"8",nodeName,gantryId,ins.getParentNodeType(),gantryId,ins.getOrgType(),ins.getDisplayLevel(),maxNum,createTime);
            map.put(gantryId,1);
        }
        /* 循环更新状态 */
        for(Map.Entry<String, InfoNodeStatus> nodeStatusEntry : nodeStatusCheckMap.entrySet()) {
            InfoNodeStatus unit = nodeStatusEntry.getValue();
            String gantryId = unit.getOrgId();
            exceptionLevel = -3;
            Integer controlStatus = controlStatusMap.get(gantryId);
            /* 主备均异常 */
            if(controlStatus != null && controlStatus == 3) {
                /* 提升异常等级 */
                exceptionLevel = 1;
            }
            InfoNodeStatusTrace infoNodeStatusTrace = infoNodeStatusTraceService.selectOne(unit.getNodeId(),unit.getNodeType());
            int status = (unit.getStatus() == 0) ? 0 : exceptionLevel;
            String desc = (unit.getStatus() == 0) ? null : unit.getDescription();
            /* rsu控制器状态，暂不更新到异常跟踪表 */
            if(unit.getNodeType().equals("8") == false) {
                operaStatus(infoNodeStatusTrace,status,unit.getOrgId(),unit.getOrgType(),unit.getNodeId(),unit.getNodeType(),desc,unit.getNodeName(),unit.getStatusCheckTime());
            }
            saveNode(unit.getNodeId(),unit.getNodeType(),unit.getNodeName(),unit.getParentNodeId(),unit.getParentNodeType(),
                    unit.getOrgId(),unit.getOrgType(),unit.getDisplayLevel(),status,unit.getStatusCheckTime());
        }
        return map;
    }

    private int rsuMainStatusCheck(String rsuStatus,String gantryId,Integer orgType,
                               String nodeType,String nodeId,String nodeName,
                               Date createTime,String prefix,Map<String,InfoNodeStatus> nodeStatusMap, int exceptionLevel,
                               Map<String, InfoNodeStatus> nodeStatusCheckMap){
        int status = 0;
        String desc = null;
        if(rsuStatus.equals("11") || rsuStatus.equals("21")){
            status = 0;
        }else{
            status = exceptionLevel;
            desc = rsuName+prefix;
        }
        InfoNodeStatus infoNodeStatus = nodeStatusMap.get(nodeType);
        String parentNodeType = infoNodeStatus.getParentNodeType();
        Integer displayLevel = infoNodeStatus.getDisplayLevel();
        InfoNodeStatus nodeStatusCheck = new InfoNodeStatus();
        nodeStatusCheck.setNodeId(nodeId);
        nodeStatusCheck.setNodeType(nodeType);
        nodeStatusCheck.setNodeName(nodeName);
        nodeStatusCheck.setParentNodeId(gantryId);
        nodeStatusCheck.setParentNodeType(parentNodeType);
        nodeStatusCheck.setOrgId(gantryId);
        nodeStatusCheck.setOrgType(orgType);
        nodeStatusCheck.setDisplayLevel(displayLevel);
        nodeStatusCheck.setStatus(status);
        nodeStatusCheck.setStatusCheckTime(createTime);
        nodeStatusCheck.setDescription(desc);
        nodeStatusCheckMap.put(nodeId, nodeStatusCheck);
        return status;
    }

    private int rsuTemperatureCheck(String rsuTemperature,String gantryId,Integer orgType,String nodeType,
                                String nodeId,String nodeName,Date createTime,String prefix,
                                Map<String,InfoNodeStatus> nodeStatusMap, int exceptionLevel,
                                Map<String, InfoNodeStatus> nodeStatusCheckMap){
        Threshold threshold = infoNodeStatusTraceService.selectThreshold(16);
        Float s1 = Float.parseFloat(threshold.getValue());
        float rate = Float.parseFloat(rsuTemperature);
        int status = 0;
        String desc = null;
        if(StringUtils.isBlank(rsuTemperature)){
            status = -2;
        }else{
            if(rate < s1){
                status = 0;
            }else{
                status = exceptionLevel;
                desc = prefix+"高于"+s1;
            }
        }
        InfoNodeStatus infoNodeStatus = nodeStatusMap.get(nodeType);
        String parentNodeType = infoNodeStatus.getParentNodeType();
        Integer displayLevel = infoNodeStatus.getDisplayLevel();
        InfoNodeStatus nodeStatusCheck = new InfoNodeStatus();
        nodeStatusCheck.setNodeId(nodeId);
        nodeStatusCheck.setNodeType(nodeType);
        nodeStatusCheck.setNodeName(nodeName);
        nodeStatusCheck.setParentNodeId(nodeId);
        nodeStatusCheck.setParentNodeType(parentNodeType);
        nodeStatusCheck.setOrgId(gantryId);
        nodeStatusCheck.setOrgType(orgType);
        nodeStatusCheck.setDisplayLevel(displayLevel);
        nodeStatusCheck.setStatus(status);
        nodeStatusCheck.setStatusCheckTime(createTime);
        nodeStatusCheck.setDescription(desc);
        nodeStatusCheckMap.put(nodeId, nodeStatusCheck);
        return status;
    }

    private int rsuControlNetWrokCheck(String controlNetWrok,String gantryId,Integer orgType,String nodeType,String nodeId,
                                   String nodeName,Date createTime,String prefix,
                                   Map<String,InfoNodeStatus> nodeStatusMap, int exceptionLevel,
                                   Map<String, InfoNodeStatus> nodeStatusCheckMap ){
        int status = 0;
        String desc = null;
        if(controlNetWrok.equals("1")){
            status = 0;
        }else if(controlNetWrok.equals("2")){
            status = exceptionLevel;
            desc = rsuName + prefix;
        }
        InfoNodeStatus infoNodeStatus = nodeStatusMap.get(nodeType);
        String parentNodeType = infoNodeStatus.getParentNodeType();
        Integer displayLevel = infoNodeStatus.getDisplayLevel();
        InfoNodeStatus nodeStatusCheck = new InfoNodeStatus();
        nodeStatusCheck.setNodeId(nodeId);
        nodeStatusCheck.setNodeType(nodeType);
        nodeStatusCheck.setNodeName(nodeName);
        nodeStatusCheck.setParentNodeId(nodeId);
        nodeStatusCheck.setParentNodeType(parentNodeType);
        nodeStatusCheck.setOrgId(gantryId);
        nodeStatusCheck.setOrgType(orgType);
        nodeStatusCheck.setDisplayLevel(displayLevel);
        nodeStatusCheck.setStatus(status);
        nodeStatusCheck.setStatusCheckTime(createTime);
        nodeStatusCheck.setDescription(desc);
        nodeStatusCheckMap.put(nodeId, nodeStatusCheck);
        return status;
    }

    private int rsuPsamStatusCheck(String psamStatus,String gantryId,Integer orgType,String nodeType,String rsuName,
                               String nodeName,String controlOrder, String nodeId,Date createTime,
                               Map<String,InfoNodeStatus> nodeStatusMap, int exceptionLevel,
                               Map<String, InfoNodeStatus> nodeStatusCheckMap ){
        int status = 0;
        String desc = null;
        if(psamStatus.equals("1")){
            status = 0;
        }else if(psamStatus.equals("2")){
            status = exceptionLevel;
            desc = rsuName + ConstantEnum.RSU_PSAM_ERROR.getNodeDesc();
        }else if(psamStatus.equals("3")){
            status = exceptionLevel;
            desc = rsuName + ConstantEnum.RSU_PSAM_UNAUTH.getNodeDesc();
        }else if(psamStatus.equals("4")){
            status = exceptionLevel;
            desc = rsuName + ConstantEnum.RSU_PSAM_AUTH_FAIL.getNodeDesc();
        }
        String parentNodeId = gantryId + split + controlOrder;
        InfoNodeStatus infoNodeStatus = nodeStatusMap.get(nodeType);
        String parentNodeType = infoNodeStatus.getParentNodeType();
        Integer displayLevel = infoNodeStatus.getDisplayLevel();
        InfoNodeStatus nodeStatusCheck = new InfoNodeStatus();
        nodeStatusCheck.setNodeId(nodeId);
        nodeStatusCheck.setNodeType(nodeType);
        nodeStatusCheck.setNodeName(nodeName);
        nodeStatusCheck.setParentNodeId(parentNodeId);
        nodeStatusCheck.setParentNodeType(parentNodeType);
        nodeStatusCheck.setOrgId(gantryId);
        nodeStatusCheck.setOrgType(orgType);
        nodeStatusCheck.setDisplayLevel(displayLevel);
        nodeStatusCheck.setStatus(status);
        nodeStatusCheck.setStatusCheckTime(createTime);
        nodeStatusCheck.setDescription(desc);
        nodeStatusCheckMap.put(nodeId, nodeStatusCheck);
        return status;
    }

    private void rsuRSUAnteTempStatus(String antennalTemperature,String gantryId,Integer orgType,String nodeType,String nodeName,String antennaId,Date createTime,String prefix,Map<String,InfoNodeStatus> nodeStatusMap){
        Threshold threshold = infoNodeStatusTraceService.selectThreshold(17);
        Float s1 = Float.parseFloat(threshold.getValue());
        Float temp = Float.parseFloat(antennalTemperature);
        int status;
        String desc = "";
        if(StringUtils.isBlank(antennalTemperature)){
            status = -2;
        }else{
            if(temp < s1){
                status = 0;
            }else {
                status = 1;
                desc = prefix + "高于"+s1;
            }
        }
        String nodeId = gantryId + split + antennaId;
        handleDate(nodeStatusMap,nodeType,nodeId,status,gantryId,gantryId,orgType,desc,nodeName,createTime);
    }
    private void rsuRSUAnteStatus(String antennalStatus, String gantryId, Integer orgType, String nodeType, String nodeName, String antennaId, Date createTime, String statusDesc,Map<String,InfoNodeStatus> nodeStatusMap ){
        String desc = null;
        int status = 0;
        if(antennalStatus.equals("1")){
            status = 0;
        }else if(antennalStatus.equals("2")) {
            status = 1;
            desc = statusDesc;
        }
        String nodeId = gantryId + split + antennaId;
        handleDate(nodeStatusMap,nodeType,nodeId,status,gantryId,gantryId,orgType,desc,nodeName,createTime);
    }

    public void handleDate(Map<String,InfoNodeStatus> nodeStatusMap, String nodeType, String nodeId, Integer status, String gantryId, String parentNodeId, Integer orgType, String desc, String nodeName, Date createTime){
        InfoNodeStatus infoNodeStatus = nodeStatusMap.get(nodeType);
        String parentNodeType = infoNodeStatus.getParentNodeType();
        Integer displayLevel = infoNodeStatus.getDisplayLevel();
        InfoNodeStatusTrace infoNodeStatusTrace = infoNodeStatusTraceService.selectOne(nodeId, nodeType);
        operaStatus(infoNodeStatusTrace,status,gantryId,orgType,nodeId,nodeType,desc,nodeName,createTime);
        saveNode(nodeId,nodeType,nodeName,nodeId,parentNodeType,parentNodeId,orgType,displayLevel,status,createTime);
    }

    @Transactional
    public void addStatus(String orgId, Integer orgType,String nodeId, String nodeType,String description,Integer level,String nodeName,Date startTime){
        saveStatus(orgId,orgType,nodeId,nodeType,description,level,nodeName,startTime);
        // 插入异常信息表
        InfoMessage infoMessage = new InfoMessage();
        infoMessage.setCreateTime(new Date());
        infoMessage.setMessage(description);
        infoMessage.setOpFlag(0);
        infoMessage.setOrgId(orgId);
        infoMessage.setOrgType(orgType);
        infoMessage.setNodeId(nodeId);
        infoMessage.setNodeType(nodeType);
        infoMessage.setLevel(level);
        // 插入异常消息
        infoUserMessageService.insertMessage(infoMessage);
        List<Integer> list = infoUserMessageService.selectUserByOrgId(orgId, orgType);
        for(Integer userId : list){
            // 插入异常消息给用户
            InfoUserMessage infoUserMessage = new InfoUserMessage();
            infoUserMessage.setMessageId(infoMessage.getMessageId());
            infoUserMessage.setUserId(userId);
            infoUserMessage.setOpFlag(0);
            infoUserMessage.setReadFlag(0);
            infoUserMessageService.insertUserMessage(infoUserMessage);
        }
    }
    @Transactional
    public void updateStatus(InfoNodeStatusTrace infoNodeStatusTrace,String nodeId, String nodeType,Date endTime){
        // 插入到状态表
        Integer datePoor = DateUtils.getDatePoor2(endTime, infoNodeStatusTrace.getStartTime());
        /* 只保存大于等于0的记录 */
        if(datePoor >= 0) {
            infoNodeStatusTrace.setDuration(datePoor);
            infoNodeStatusTrace.setEndTime(endTime);
            infoNodeStatusTraceService.insertHistory(infoNodeStatusTrace);
        }
        infoNodeStatusTraceService.delete(nodeId,nodeType);
        //String key = "InfoNodeStatusTrace"+":"+nodeId+":"+nodeType;
        //redisUtil.delete(key);
        InfoMessage infoMessages = null;
        try{
            infoMessages = infoUserMessageService.selectMessage(nodeId, nodeType);
        }catch (Exception e){
            logger.error("查询报错信息出错");
            logger.error(e.getMessage());
        }
        // 更新异常消息
        infoUserMessageService.updateMessage(nodeId,nodeType);
        if(infoMessages != null){
            infoUserMessageService.updateUserMessage(infoMessages.getMessageId());
        }
    }

    @Transactional
    public void saveNode(String nodeId,String nodeType,String nodeName,String parentNodeId,String parentNodeType,String orgId,Integer orgType,Integer displayLevel, Integer status, Date checkTime){
        infoNodeStatusService.delete(nodeId,nodeType);
        InfoNodeStatus infoNodeStatus = new InfoNodeStatus();
        infoNodeStatus.setNodeId(nodeId);
        infoNodeStatus.setNodeType(nodeType);
        infoNodeStatus.setNodeName(nodeName);
        infoNodeStatus.setParentNodeId(parentNodeId);
        infoNodeStatus.setParentNodeType(parentNodeType);
        infoNodeStatus.setOrgId(orgId);
        infoNodeStatus.setOrgType(orgType);
        infoNodeStatus.setDisplayLevel(displayLevel);
        int st = status != null?status:0;
        infoNodeStatus.setStatus(st);
        infoNodeStatus.setStatusCheckTime(checkTime);
        infoNodeStatus.setStatusChangeTime(new Date());
        infoNodeStatusService.insert(infoNodeStatus);
    }

    private void operaStatus(InfoNodeStatusTrace infoNodeStatusTrace,Integer status,String orgId,Integer orgType,String nodeId,String nodeType,String description,String nodeName,Date createTime){
        if(infoNodeStatusTrace != null){
            // 已经记录异常，判断现在是否为正常
            if(status <=0){
                updateStatus(infoNodeStatusTrace,nodeId,nodeType,createTime);
            }else{
                // 异常发生变化 excLevel肯定大于0 status肯定大于0
                Integer excLevel = infoNodeStatusTrace.getExcLevel();
                if(status.intValue() != excLevel.intValue()){
                    // 插入历史记录，历史看记录是原有状态
                    updateStatus(infoNodeStatusTrace,nodeId,nodeType,createTime);
                    // 插入新纪录
                    infoNodeStatusTrace.setExcLevel(status);
                    infoNodeStatusTrace.setDescription(description);
                    saveStatus(orgId,orgType,nodeId,nodeType,description,status,nodeName,createTime);
                }
            }
        }else{
            if(status > 0){
                addStatus(orgId,orgType,nodeId,nodeType,description,status,nodeName,createTime);
            }
        }
    }

    public void saveStatus(String orgId, Integer orgType,String nodeId, String nodeType,String description,Integer status,String nodeName,Date startTime){
        InfoNodeStatusTrace ds = new InfoNodeStatusTrace();
        ds.setOrgId(orgId);
        ds.setOrgType(orgType);
        ds.setNodeId(nodeId);
        ds.setNodeType(nodeType);
        ds.setNodeName(nodeName);
        ds.setStartTime(startTime);
        ds.setDescription(description);
        ds.setExcLevel(status);
        ds.setWarnFlag(0);
        infoNodeStatusTraceService.insert(ds);
        //String key = "InfoNodeStatusTrace"+":"+nodeId+":"+nodeType;
        // 数据库增加的同时，redis里面放一份数据
        //redisUtil.setEx(key, JSONObject.toJSONString(ds),10, TimeUnit.MINUTES);
    }
}
